/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * All Rights Researved.
 *
 * This library is developed and distributed for free usage,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * You can redistribute and/or modify it under the terms of the
 * Simplified BSD License
 *
 *
 *
 *
 *
 *
 *
 * Select items from list (JList) to table on the right
 * Deprecated, use SelectItemsPane i
 * @author: jin Chen
 * @date: Aug 19, 2003$
 * @version: 1.0
 */
package edu.psu.geovista.app.pcp.toolkits.selectcontrol;

import edu.psu.geovista.app.pcp.toolkits.ColorItemList;
import edu.psu.geovista.app.pcp.toolkits.table.ConfigureTable;

import javax.swing.*;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Hashtable;

public abstract class ListControlPane extends JPanel {
    ButtonListner btnListener=new ButtonListner();
    protected Hashtable buttons=new Hashtable();
    protected int[] selectedRows=null;  // 
    public ListControlPane() {
         initComponents();


        //myTable.getModel().get
    }
    /**
     * To set weight of columns
     *  
     * @param weights  weight of each column width. 0 means does not matter
     */
    public void setColumnsWidth(int[] weights) {
        double total=0;
        for (int i=0;i<weights.length ;i++){
            total=total+weights[i];
        }
        double[] ws=new double[weights.length ];
        for (int i=0;i<ws.length ;i++){
            ws[i]=weights[i]/total;
        }
        setColumnsWidth(ws);

    }
    /**
     *
     * @param weights  Array contains the weight of each column width. They must be expressed  in term of  a column weight/total weight
     */
    protected void setColumnsWidth(double[] weights){
        int numOfColumn=myTable.getColumnCount();
        if(weights==null||weights.length !=numOfColumn){
                 new IllegalArgumentException(this.getClass().getName() +" is passed a null argument or the array length is not correct");
                 return;
        }
        TableColumnModel cm = this.myTable.getColumnModel();
        int totalwidth=cm.getTotalColumnWidth() ;
        for (int i=0;i<numOfColumn;i++){
            int w=(int)Math.round(totalwidth*weights[i]);
            if(w>0){
                TableColumn c1 = cm.getColumn(i); //.getColumn("Name");
                c1.setPreferredWidth(w);
                //c1.setMinWidth(w);
            }
            //c1.setMaxWidth(50);
        }

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;


       //create components

        mainP = new javax.swing.JPanel();
        btnP = new javax.swing.JPanel();

        tableP = new javax.swing.JPanel();
        TableScrollPane = new javax.swing.JScrollPane();
        myTable = new ConfigureTable();
        listP = new javax.swing.JPanel();
        ListScrollPane = new javax.swing.JScrollPane();
        myList = new ColorItemList();


        //placement
        setLayout(new java.awt.GridBagLayout());
        setPreferredSize(new java.awt.Dimension(400, 375));

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;

        mainP.setLayout(new java.awt.GridBagLayout());


        btnP.setLayout(new java.awt.GridLayout(9, 1));


        gridBagConstraints = new java.awt.GridBagConstraints();
       // gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        /*gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;*/
        mainP.add(btnP, gridBagConstraints);

        tableP.setLayout(new java.awt.BorderLayout());

        tableP.setBorder(new javax.swing.border.TitledBorder(""));
        tableP.setPreferredSize(new java.awt.Dimension(473, 349));
        //TableScrollPane.setBorder(new javax.swing.border.TitledBorder("Visible"));
        //Vector colName=new Vector();
        //colName.add("Index");colName.add("Name");colName.add("Interval");colName.add("DisplayType");
        //VisibleAxisTable.setModel(this.getVisibleAxisTableModel( this.yaxisList.size()));

        TableScrollPane.setViewportView(myTable);

        tableP.add(TableScrollPane, java.awt.BorderLayout.CENTER);
       //tableP.setBorder(new javax.swing.border.TitledBorder("Visible"));

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 2.0;
        gridBagConstraints.weighty = 1.0;
        mainP.add(tableP, gridBagConstraints);

        listP.setLayout(new java.awt.BorderLayout());


        ListScrollPane.setViewportView(myList);

        listP.add(ListScrollPane, java.awt.BorderLayout.CENTER);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        mainP.add(listP, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(mainP, gridBagConstraints);

        initButtons()   ;
    }
    /*******************************************************************************************************
     *                GUI
     *******************************************************************************************************/
     public void setMainSectionName(String name) {
        mainP.setBorder(new javax.swing.border.TitledBorder(name));
     }
    public void setListSectionName(String name) {
        listP.setBorder(new javax.swing.border.TitledBorder(name));
    }
    public void setTableSectionName(String name) {
        tableP.setBorder(new javax.swing.border.TitledBorder(name));
    }
    /*******************************************************************************************************
     *                List
     *******************************************************************************************************/
    protected abstract void reset();
    public void setListData(Object[] items) {
        if(myTable.getRowCount() >0)
             myTable.removeAllRow() ;
        //myList.setListData(new Object[]{});
        this.myList.setListData(items);
        this.myList.resetColor() ;//make all item not gray
       /* ListModel model=myList.getModel() ;
        for (int i=0;i<model.getSize();i++){
            System.out.println(""+model.getElementAt(i) );
        }
       */

    }

    /*******************************************************************************************************
     *                table
     *******************************************************************************************************/
    //1.create tableModel //2. init values
    protected abstract void intiTable();

    public void setTableModel(TableModel dataModel) {
        this.myTable.setModel(dataModel);
    }
    public void setValueAt(Object value,int row, int col) {
        myTable.setValueAt(value,row,col);
    }
     public Object[] getColumnValues(String  colName){
         return myTable.getColumnValues(colName);
     }
      public Object[] getColumnValues(int col){
         return myTable.getColumnValues(col);
     }

    /*******************************************************************************************************
     *                button
     *******************************************************************************************************/
    protected void initButtons() {
        String[] names=new String[]{"Right","Left","Right all","Left all","Up","Down","Apply"};
        this.addButtons(names);

    }

    public void addButtons(String[] names) {
        int numBtn=names.length;
        btnP.removeAll() ;

        this.btnP.setLayout(new java.awt.GridLayout(numBtn, 1)) ;
        for (int i=0;i<numBtn ;i++){
             JButton btn=new JButton(names[i]);
             btn.setMargin(new Insets(2,2,2,2));
             btn.setName(names[i]);
             btn.addActionListener(this.btnListener );
             btnP.add(btn);
             this.buttons.put(names[i],btn);
        }
    }
    public JButton getButton(String name) {
        return (JButton) this.buttons.get(name);
    }
    /**
     * you can add any component in the middle panel which contain the button.
     * All components in the panel is listed from top to bottom in one column. The sequence is same as the order they are added
     * It is your responsibility to listen the component's behavoir
     *
     * @param comp
     */
    public void addComponentToMiddlePanel(JComponent comp) {
        btnP.add(comp);
        Component[] comps=btnP.getComponents();
        if(comps!=null&&comps.length >0){
            int numOfComp=comps.length ;
            this.btnP.setLayout(new java.awt.GridLayout(numOfComp+1, 1)) ;
        }
        else{
            this.btnP.setLayout(new java.awt.GridLayout(1, 1)) ;
        }
    }
    public void setButtonPane(SingleButtonsPane p) {
        /*mainP.remove(this.btnP);
        GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        mainP.add(p, gridBagConstraints);*/
        btnP.removeAll();
        btnP.setLayout(new BorderLayout());
        btnP.add(p);
        mainP.invalidate();
        p.addActionListnerForAll(this.btnListener );
        this.revalidate() ;

    }
    public void setNumOfComponentInMiddlePanel(int numOfComp) {

    }
    /*******************************************************************************************************
     *                Event
     *******************************************************************************************************/
    protected  abstract void actOnButtonClick(String btnName) throws Exception;
    /**
     *
     * @param items
     */
    protected  void moveRight(){
         Object[] names=myList.getSelectedValues() ;

        for (int i=0;i<names.length ;i++){
                String name=(String) names[i];
                if(!myTable.isRecordContained("Name",name) ){
                    this.addRecord(name);
                    this.myList.colorItem(name,true);
                }
        }
    }
    /**
     * Move all items on the left to right
     */
    protected void moveAllRight(){
        ListModel model=myList.getModel();
        for (int i=0;i<model.getSize() ;i++){
                String name=(String) model.getElementAt(i) ;
                if(!myTable.isRecordContained("Name",name) ){
                    this.addRecord(name);

                }
                this.myList.colorAllItem(true);
        }
    }
    /**
     *  
     *  
     * @param name  the key attribute of the record
     */
    protected abstract void addRecord(String name);/*{
        Object[] arow={new Integer(-1),name, YAxis.DTYPE_Nml};
                this.myTable.addRow(arow);
    }*/
    /**
     *  
     *  
     * deprecate
     */
    protected  void moveSingleItemLeft(){
        // Add your handling code here:
        int index=this.myTable.getSelectedRow() ;
        if(index<0)return ;

          String name= (String) myTable.getValueAt(index,"Name");
          if(name!=null){
            this.myTable.removeRow(index);
            this.myList.colorItem(name,false);
          }
    }
    /**
     *  
     *  
     */
    protected  void moveLeft(){
        // Add your handling code here:
        //int[] indexs=this.myTable.getSelectedRows();
        int[] indexs=this.getSelectedRows() ;
        if(indexs==null||indexs.length <=0)return ;

        Arrays.sort(indexs);
        for (int i=indexs.length -1;i>=0;i--){
          String name= (String) myTable.getValueAt(indexs[i],"Name");
          if(name!=null){
            this.myTable.removeRow(indexs[i]);
            this.myList.colorItem(name,false);
          }
        }
        //this.setSelectedRows(null);

    }
    protected  void moveAllLeft(){
        this.myTable.removeAllRow() ;
        this.myList.colorAllItem(false);
         //this.setSelectedRows(null);

    }
    protected  void moveUp(){

        int[] rows=this.getSelectedRows() ;
        myTable.moveRowsUp(rows);
        this.updateSelectedRows(-1);
    }
    protected  void moveDown(){

        int[] rows=this.getSelectedRows() ;
        myTable.moveRowsDown(rows);
        this.updateSelectedRows(1);
    }

    protected void moveTop(){
        int[] rows=this.getSelectedRows() ;
        if(rows!=null&&rows.length >0){
            myTable.moveTop(rows);
        }
    }
    protected void moveBottom(){
        int[] rows=this.getSelectedRows() ;
        if(rows!=null&&rows.length >0){
            myTable.moveBottom(rows);
        }
    }
    protected void apply(){
        //this.setSelectedRows(null);
    }
    protected int[] getSelectedRows(){
         //if(this.selectedRows ==null){
             this.selectedRows = myTable.getSelectedRows();
         //}
         return this.selectedRows ;
    }
    /**
     * update the selected row
     * @param delta -1 means make selected row= current selected row -1.
     */
    protected void updateSelectedRows(int delta){
        for (int i=0;i<this.selectedRows.length ;i++){
            int expect=selectedRows[i]+delta;
            if(expect>=0&&expect<this.myTable.getRowCount() ) {
               selectedRows[i]=expect;
            }
        }
        //select rows
        myTable.setRowSelectionAllowed(true);
         ListSelectionModel model=myTable.getSelectionModel();
        for (int i=0;i<selectedRows.length ;i++){
            //myTable.setRowSelectionInterval(selectedRows[i],selectedRows[i]);

            model.addSelectionInterval(selectedRows[i],selectedRows[i]);
        }
    }

    public void setSelectedRows(int[] selectedRows) {
        this.selectedRows = selectedRows;

    }
    /**
     *  
     */
    public void setSelectedAttributes(String[] attnames){
        if(attnames==null||attnames.length <=0){
            this.moveAllLeft();
            return;
        }
        int[] indices=new int[attnames.length ];
        for (int i=0;i<indices.length ;i++){
            indices[i]=myList.getIndex(attnames[i]);
        }
        myList.setSelectedIndices(indices);
        this.moveRight();


    }
    public void selectAllAttributes(){
        this.moveAllRight();
    }
    /*public void setSelectedListItems(int[] indice) {
        myList.setSelectedIndices(indice);
    }*/
    // Variables declaration - do not modify

    protected ConfigureTable myTable;
    protected javax.swing.JScrollPane TableScrollPane;
    protected javax.swing.JPanel tableP;
    protected ColorItemList myList;
    protected javax.swing.JScrollPane ListScrollPane;
    protected javax.swing.JPanel listP;

    protected javax.swing.JPanel btnP;
    protected javax.swing.JPanel mainP;


    private class ButtonListner implements ActionListener{
            public void actionPerformed(java.awt.event.ActionEvent evt) {

                JButton btn=(JButton) evt.getSource();

                //System.out.println("click on :"+btn.getName() );
                try {
                    actOnButtonClick(btn.getName());
                } catch (Exception e) {
                    //JOptionPane.showMessageDialog(this,e.getMessage());
                }
            }
    }


    

}
